package main
// node_exporter的job改造为consul的服务发现
// 通过该代码可以实现任何服务向consul的注册
import (
	"fmt"
	consul "github.com/hashicorp/consul/api"
	"log"
)

type client struct {
	consul *consul.Client
}

func NewConsulClient(addr string) (*client, error) {
	config := consul.DefaultConfig()
	config.Address = addr
	c, err := consul.NewClient(config)
	if err != nil {
		return nil, err
	}
	return &client{consul: c}, nil
}

// 注册服务
func (c *client) ServiceRegister(srvName, srvHost string, srvPort int, healthyCheckPath string, metaMap map[string]string) error {

	reg := new(consul.AgentServiceRegistration)
	reg.Name = srvName

	thisId := fmt.Sprintf("%s_%d", srvHost, srvPort)
	reg.ID = thisId
	reg.Port = srvPort
	reg.Address = srvHost
	reg.Meta = metaMap
	log.Printf("ServiceRegisterStart :%v", thisId)
	//增加check
	check := new(consul.AgentServiceCheck)
	check.HTTP = fmt.Sprintf("http://%s:%d%s", reg.Address, reg.Port, healthyCheckPath)
	//设置超时 5s。
	check.Timeout = "2s"
	check.DeregisterCriticalServiceAfter = "5s"
	//设置间隔 5s。
	check.Interval = "5s"
	//注册check服务。
	//reg.Check = check

	return c.consul.Agent().ServiceRegister(reg)
}

// Service return a service
func (c *client) GetService(service, tag string) ([]*consul.ServiceEntry, error) {
	passingOnly := true
	ss, _, err := c.consul.Health().Service(service, tag, passingOnly, nil)
	if len(ss) == 0 && err == nil {
		return nil, fmt.Errorf("service ( %s ) was not found", service)
	}

	return ss, err
}

// 根据server id注销服务
func (c *client) DeRegister(id string) error {
	return c.consul.Agent().ServiceDeregister(id)
}
func main() {
	// 自己的consul地址
	c, err := NewConsulClient("http://192.168.3.200:8500")
	if err != nil {
		log.Printf("NewConsulClient.err:%v", err)
		return
	}
    // 两个node_exporter地址
	nodes := []string{
		"192.168.3.200",
		"192.168.3.201",
	}

	nodeExporterSrv := "node_exporter"
	for _, h := range nodes {

		// 可以大一些标签
		m := map[string]string{"region": "bj", "cloud": "huawei"}
		// node_exporter地址9100
		err = c.ServiceRegister(nodeExporterSrv, h, 9100, "/", m)
		if err != nil {
			log.Printf("[ServiceRegister.err][srv:%v][host:%v][err:%v]", nodeExporterSrv, h, err)
		} else {
			log.Printf("[ServiceRegister.success][srv:%v][host:%v]", nodeExporterSrv, h)
		}
	}

	ss, err := c.GetService(nodeExporterSrv, "")
	for _, s := range ss {
		log.Printf("[c.GetService][service_id:%v][err:%v]", s.Service.ID, err)
		//c.DeRegister(s.Service.ID) // 注销服务
	}

}
